package com.tuanbiao.presenter;

import android.text.TextUtils;
import android.view.KeyEvent;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.OnLifecycleEvent;

import com.abiao.lib_utils.Preconditions;
import com.hzjq.data.callback.OnResultCallback;
import com.hzjq.data.entity.CapDelayEntity;
import com.hzjq.data.entity.PlanEntity;
import com.hzjq.data.entity.PmEntity;
import com.hzjq.data.entity.UIDRule;
import com.hzjq.data.hzjq.entity.CapRecordEntity;
import com.hzjq.lib.BlastKool;
import com.hzjq.lib.bean.PlanInfo;
import com.hzjq.lib.cap.bean.ReadResult;
import com.hzjq.lib.cap.read.ReadCapLoader;
import com.hzjq.lib.cap.scan.ScanCapLoader;
import com.hzjq.lib.cap.scan.Scanner;
import com.hzjq.lib.config.param.BlastLoader;
import com.tuanbiao.R;
import com.tuanbiao.base.mvp.BasePresenter;
import com.tuanbiao.constants.Constants;
import com.tuanbiao.controllers.DetonatorController;
import com.tuanbiao.data.callback.OnBaseResultCallback;
import com.tuanbiao.data.callback.OnDetonatorsCallback;
import com.tuanbiao.data.entity.KeepSortItem;
import com.tuanbiao.events.DetonatorRegisterEvent;
import com.tuanbiao.keyevent.KeyEventHelper;
import com.tuanbiao.models.DetonatorModel;
import com.tuanbiao.models.action.DetonatorAction;
import com.tuanbiao.utils.LibCollections;
import com.tuanbiao.utils.MediaUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;

import timber.log.Timber;

/**
 * @author abiao
 * @since 2022/4/8 14:58
 */
public class DetonatorRegisterPresenter extends BasePresenter<DetonatorModel, DetonatorController.RegisterView> implements DetonatorController.RegisterPresenter, DetonatorAction {
    private PlanEntity mPlanEntity;
    private PlanInfo mPlanInfo;
    private PmEntity currentProject;
    private String mPlantStr;
    private ReadCapLoader readCapLoader;
    private Scanner scanCapLoader;
    private int repeatCount = 0;
    private ArrayList<CapRecordEntity> repeatCaps = new ArrayList<>();
    //是否正在扫描雷管
    private CapDelayEntity mCapDelayEntity;
    private boolean isAddNewRow;

    public DetonatorRegisterPresenter(DetonatorModel model, DetonatorController.RegisterView rootRegisterView) {
        super(model, rootRegisterView);
    }


    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void init(DetonatorRegisterEvent entityEvent) {
        mPlanEntity = entityEvent.getEntity();
        Timber.i(TAG + "#initEvent#plan:" + mPlanEntity);
        if (null != mPlanEntity) mPlantStr = String.valueOf(mPlanEntity.getId());
        EventBus.getDefault().removeStickyEvent(entityEvent);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void init() {
        currentProject = mModel.getCurrentProject();
        readCapLoader = BlastKool.Companion.loader().read();
        scanCapLoader = BlastKool.Companion.loader().scan();
        scanCapLoader.setTabScanModeKeysCallback(KeyEventHelper.getInstance().getScanModeKeys(), b -> {
            Timber.i(TAG + "#setTabScanModeKeysCallback:");
            mRootView.onScannerTypeChange(b);
        });
        if (TextUtils.isEmpty(mPlantStr)) return;
        scanCapLoader.open(mPlantStr, scanResult -> {
            Timber.i(TAG + "#scanCapSingle#result:" + scanResult.getStatus() + ",msg:" + scanResult.getMsg());
            if (scanResult.getStatus() == Constants.CodeErrorCode.SUCCESS) {
                MediaUtils.playSound(R.raw.sound);
                refreshDetonators(scanResult.getCap().getConvertUid());
                getDelay();
            } else if (scanResult.getStatus() == Constants.CodeErrorCode.REPEAT) {
                MediaUtils.playSound(R.raw.repeat_scan);
                mRootView.showScanRepeat(null, scanResult);
            } else if (scanResult.getStatus() == Constants.CodeErrorCode.CODE_ERROR) {
                MediaUtils.playSound(R.raw.code_error);
            }
            mRootView.showMessage(scanResult.getMsg());
        });
        Timber.i(TAG + "#init#plan:" + mPlanEntity);
        Preconditions.checkNotNull(mPlanEntity, "planEntity can not be null");
        mRootView.showLoading();
        getDelay();
    }

    private void getDelay() {
        mModel.getDelay(new OnBaseResultCallback<CapDelayEntity>() {
            @Override
            public void onSuccess(CapDelayEntity entity) {
                Timber.i("getDelay:" + entity.isAddNewRow());
                mCapDelayEntity = entity;
                isAddNewRow = entity.isAddNewRow();
                mRootView.showAddRow(entity.isAddNewRow());
                mRootView.showF1Delay(entity.getDelay1());
                mRootView.showF2Delay(entity.getDelay2());
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showF1Delay(0);
                mRootView.showF2Delay(0);
            }

            @Override
            public void onFinish() {
                mRootView.hideLoading();
            }
        });
    }


    @Override
    public boolean useEventBus() {
        return true;
    }

    @Override
    public int getMaxCapCount() {
        return BlastLoader.Companion.getMaxSupportPlanCapSize();
    }

    @Override
    public void getDetonatorsByPlanId() {
        if (TextUtils.isEmpty(mPlantStr)) {
            mRootView.showMessage("获取雷管列表失败，方案ID为空");
            return;
        }
        mModel.queryDetonatorByPlanId(mPlantStr, new OnDetonatorsCallback() {
            @Override
            public void onSuccess(List<CapRecordEntity> entities, PlanInfo planInfo) {
                Timber.i(TAG + "#getDetonatorsByPlanId#" + entities + ",planInfo:" + planInfo);
                mRootView.setDetonators(entities);
                mPlanInfo = planInfo;
                mRootView.showStatistics(planInfo);
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    @Override
    public void menuReadOnline(int count) {
        if (!checkReadOrScan(count)) {
            return;
        }
        repeatCount = 0;
        repeatCaps.clear();
        readCapLoader.read(mPlantStr, () -> readCapLoader.onDestroy(), new OnResultCallback<ReadResult>() {
            @Override
            public void onResult(ReadResult readResult) {
                Timber.i("readOnline:" + readResult.isReadEnd());
                Timber.i("readOnline#repeatCaps:" + LibCollections.size(readResult.getRepeatCaps()));
                if (!LibCollections.isEmpty(readResult.getRepeatCaps())) {
                    repeatCount += LibCollections.size(readResult.getRepeatCaps());
                    repeatCaps.addAll(readResult.getRepeatCaps());
                }
                if (readResult.isReadEnd() && repeatCount > 0) {
                    mRootView.showRepeatDialog(repeatCount, repeatCaps);
                }
                if (!LibCollections.isEmpty(readResult.getNewCaps()))
                    getDelay();
                mRootView.addDetonators(readResult.getNewCaps());
                if (readResult.isReadEnd()) {
                    if (readResult.getInfo().getUidErrorCount() > 0) {
                        MediaUtils.playSound(R.raw.code_error);
                        mRootView.showUidError(readResult.getInfo().getUidErrorCount());
                    }
                    PlanInfo planInfo = readResult.getInfo();
                    mPlanInfo = planInfo;
                    mRootView.showStatistics(planInfo);
                    Timber.i("onResult#readResult:" + readResult.getInfo());
                }
            }

            @Override
            public void onFailed(@NonNull String s) {
                mRootView.showMessage(s);
                Timber.i("onResult#onFailed:" + s);
            }
        });
    }

    @Override
    public void toggleAddNewRow() {
        if (null == mCapDelayEntity) {
            mCapDelayEntity = new CapDelayEntity();
        }
        isAddNewRow = !isAddNewRow;
        mCapDelayEntity.setAddNewRow(isAddNewRow);
        Timber.i("addNewRow#" + isAddNewRow);
        mModel.setDelay(mCapDelayEntity, new OnBaseResultCallback<CapDelayEntity>() {
            @Override
            public void onSuccess(CapDelayEntity entity) {
                mRootView.showMessage(isAddNewRow ? "新增一排成功" : "减少一排成功");
                mRootView.showAddRow(isAddNewRow);
            }

            @Override
            public void onFailed(String msg) {
                Timber.w(TAG + "#addNewRow#msg:" + msg);
                mRootView.showMessage(isAddNewRow ? "新增一排失败" : "减少一排失败");
            }
        });
    }

    @Override
    public void updateFDelay(@Constants.ScannerKeyCode int scannerCode, String content) {
        long delay = Long.parseLong(content);
        if (null == mCapDelayEntity) {
            mCapDelayEntity = new CapDelayEntity();
        }
        switch (scannerCode) {
            case Constants.ScannerKeyCodes.F1:
                mCapDelayEntity.setDelay1(delay);
                mModel.setDelay(mCapDelayEntity, new OnBaseResultCallback<CapDelayEntity>() {
                    @Override
                    public void onSuccess(CapDelayEntity entity) {
                        mRootView.showMessage("修改成功");
                        mRootView.showF1Delay(delay);
                    }

                    @Override
                    public void onFailed(String msg) {
                        mRootView.showMessage(msg);
                    }
                });

                break;
            case Constants.ScannerKeyCodes.F2:
                mCapDelayEntity.setDelay2(delay);
                mModel.setDelay(mCapDelayEntity, new OnBaseResultCallback<CapDelayEntity>() {
                    @Override
                    public void onSuccess(CapDelayEntity entity) {
                        mRootView.showMessage("修改成功");
                        mRootView.showF2Delay(delay);
                    }

                    @Override
                    public void onFailed(String msg) {
                        mRootView.showMessage(msg);
                    }
                });

                break;
            default:
                break;

        }
    }

    @Override
    public void menuUpdateDelays(boolean keepSort, String startDelay, String rowDelay, String columnDelay) {
        if (keepSort) rowDelay = "0";
        mModel.setDelay(mPlantStr, keepSort, Long.parseLong(startDelay), Long.parseLong(rowDelay), Long.parseLong(columnDelay), new OnBaseResultCallback<ReadResult>() {
            @Override
            public void onSuccess(ReadResult entity) {
                getDetonatorsByPlanId();
                mRootView.showMessage("修改延时成功");
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage("修改延时失败");
            }
        });
    }

    @Override
    public boolean checkUpdateDelays(KeepSortItem keepSortItem, String startDelay, String rowDelay, String columnDelay) {
        if (TextUtils.isEmpty(startDelay)) {
            mRootView.showMessage("请输入起始延时");
            return false;
        }
        if (!TextUtils.isDigitsOnly(startDelay)) {
            mRootView.showMessage("起始延时只能是数字");
            return false;
        }
        long delay = Long.parseLong(startDelay);
        if (delay > getMaxDelay()) {
            mRootView.showMessage("起始延时不能大于" + getMaxDelay() + "ms");
            return false;
        }
        if (null == keepSortItem) {
            mRootView.showMessage("请选择排序方式");
            return false;
        }
        if (!keepSortItem.isKeepSort()) {
            if (TextUtils.isEmpty(rowDelay)) {
                mRootView.showMessage("请输入排间延时");
                return false;
            }
            if (!TextUtils.isDigitsOnly(rowDelay)) {
                mRootView.showMessage("排间延时只能是数字");
                return false;
            }
            delay = Long.parseLong(rowDelay);
            if (delay > getMaxDelay()) {
                mRootView.showMessage("排间延时不能大于" + getMaxDelay() + "ms");
                return false;
            }
        }
        if (TextUtils.isEmpty(columnDelay)) {
            mRootView.showMessage("请输入孔间延时");
            return false;
        }
        if (!TextUtils.isDigitsOnly(columnDelay)) {
            mRootView.showMessage("孔间延时只能是数字");
            return false;
        }
        delay = Long.parseLong(columnDelay);
        if (delay > getMaxDelay()) {
            mRootView.showMessage("孔间延时不能大于" + getMaxDelay() + "ms");
            return false;
        }
        return true;
    }

    @Override
    public void menuSort(List<CapRecordEntity> entities, @Constants.DetonatorSortType String sortType, @Constants.DetonatorOrderType String orderType) {
        Timber.i(TAG + "#setSort#sortType:" + sortType + ",orderType:" + orderType);
        mModel.sort(sortType, orderType, entities, new OnBaseResultCallback<String>() {
            @Override
            public void onSuccess(String sortType) {
                Timber.i(TAG + "#setSort#onSuccess");
                getDetonatorsByPlanId();
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    @Override
    public void menuInsertDetonator(CapRecordEntity selectEntity, String uid, String delay, String row, String column,UIDRule rule) {
        CapRecordEntity entity = new CapRecordEntity();
        if(uid.length() == 27){
            entity.setConvertUid(uid.substring(14));
            entity.setTubeUid(uid.substring(1,14));
            entity.setUid(BlastKool.Companion.getCapUidConvertor().restore(entity));
        } else {
            entity.setConvertUid(uid);
            String duid = BlastKool.Companion.getCapUidConvertor().restore(entity);
            entity.setUid(duid);
            if(rule == UIDRule.QH214) {
                String displayUid = BlastKool.Companion.getCapUidConvertor().convert(entity);
                entity.setConvertUid(displayUid);
                entity.setTubeUid(uid);
            }
        }
        entity.setPlanId(mPlantStr);
        entity.setDelay(Long.parseLong(delay));
        entity.setRowNumber(Integer.parseInt(row));
        entity.setHoleNumber(Integer.parseInt(column));
        Timber.i(TAG + "#insertDetonator:" + entity);
        mModel.insertDetonator(mPlantStr, entity, selectEntity, new OnBaseResultCallback<String>() {
            @Override
            public void onSuccess(String msg) {
                if (TextUtils.equals("success", msg)) {
                    mRootView.showMessage("插入成功！");
                    getDetonatorsByPlanId();
                } else {
                    mRootView.showMessage(msg);
                }
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    @Override
    public void menuClearDetonator() {
        Timber.i(TAG + "#clearDetonator");
        mModel.clearDetonator(mPlantStr, unused -> getDetonatorsByPlanId());
    }

    @Override
    public void deleteDetonator(CapRecordEntity entity) {
        mModel.deleteDetonator(entity, new OnBaseResultCallback<CapRecordEntity>() {
            @Override
            public void onSuccess(CapRecordEntity entity) {
                mRootView.showMessage("删除成功");
                getDetonatorsByPlanId();
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    @Override
    public void menuDeleteSelectedDetonator(List<CapRecordEntity> entities) {
        Timber.i(TAG + "#deleteDetonator:" + LibCollections.size(entities) + "," + entities);
        if (LibCollections.isEmpty(entities)) {
            mRootView.showMessage("请至少选择一个雷管");
            return;
        }
        mModel.deleteDetonator(entities, new OnBaseResultCallback<List<CapRecordEntity>>() {

            @Override
            public void onSuccess(List<CapRecordEntity> capRecordEntities) {
                Timber.i(TAG + "#deleteDetonator#onSuccess");
                if(mRootView != null) {
                    mRootView.showMessage("删除成功");
                    getDetonatorsByPlanId();
                }
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    @Override
    public void updateDetonator(CapRecordEntity entity) {
        mModel.updateDetonator(entity, new OnBaseResultCallback<CapRecordEntity>() {
            @Override
            public void onSuccess(CapRecordEntity entity) {
                mRootView.onDetonatorChange(entity);
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    @Override
    public long getMaxDelay() {
        return mModel.getMaxDelay();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Timber.i(TAG + "#onKeyDown#"+keyCode+" event:"+event.getAction());
        return scanCapLoader.dispatchKeyEvent(event);
    }

    @Override
    public void overRepeatCaps(ArrayList<CapRecordEntity> caps, Runnable run) {
        if (TextUtils.isEmpty(mPlantStr)) {
            mRootView.showMessage("获取雷管列表失败，方案ID为空");
            run.run();
            return;
        }
        mModel.overPlanCaps(mPlantStr, caps, run);
    }

    @Override
    public void copyCap() {
        if(!TextUtils.isEmpty(mPlantStr)) {
           // BlastKool.Companion.loader().db().copyCap(mPlantStr);
        }
    }

    @Override
    public void menuBackUpPlan(String content) {
        PlanEntity entity = new PlanEntity();
        entity.setName(content);
        mRootView.backupLoading();
        mModel.copyPlan(mPlantStr, content, new OnBaseResultCallback<Boolean>() {
            @Override
            public void onSuccess(Boolean success) {
                if (success) mRootView.showMessage("备份成功");
                else mRootView.showMessage("备份失败");
            }

            @Override
            public void onFinish() {
                mRootView.hideBackupLoading();
            }
        });
    }

    @Override
    public void menuSetRow(String content) {
        // TODO: 2022/11/2 未完成
        int row = Integer.parseInt(content);
        if (row < 1) {
            mRootView.showMessage("排数不能小于1");
            return;
        }
        if (null != mPlanInfo) {
            if (mPlanInfo.getMaxRow() <= 1) {

            } else {
                if (row > mPlanInfo.getMaxRow()) {
                    mRootView.showMessage("请输入1至" + mPlanInfo.getMaxRow() + "之间的数字");
                    return;
                }
            }

        } else {
            mRootView.showMessage("请输入1至" + mPlanInfo.getMaxRow() + "之间的数字");
            return;
        }

      //  scanCapLoader.setRow(Integer.parseInt(content));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        scanCapLoader.stop();
        scanCapLoader.close();
        readCapLoader.onDestroy();
    }



    private void refreshDetonators(String uid) {
        if (TextUtils.isEmpty(mPlantStr)) {
            mRootView.showMessage("获取雷管列表失败，方案ID为空");
            return;
        }
        mModel.queryDetonatorByPlanId(mPlantStr, new OnDetonatorsCallback() {
            @Override
            public void onSuccess(List<CapRecordEntity> entities, PlanInfo planInfo) {
                Timber.i(TAG + "#getDetonatorsByPlanId#" + entities + ",planInfo:" + planInfo);
                mRootView.setDetonators(entities);
                mPlanInfo = planInfo;
                mRootView.showStatistics(planInfo);
                mRootView.scrollToPosition(uid);
            }

            @Override
            public void onFailed(String msg) {
                mRootView.showMessage(msg);
            }
        });
    }

    private boolean checkReadOrScan(int count) {
        if (count >= getMaxCapCount()) {
            mRootView.showMessage("已达到组网的最大雷管数据，无法再导入雷管数据");
            return false;
        }
        if (null == currentProject) {
            mRootView.showMessage("未绑定项目");
            return false;
        }
        if (TextUtils.isEmpty(mPlantStr)) {
            mRootView.showMessage("未选择方案");
            return false;
        }
        return true;
    }
}
